package com.cwnu.sw.cys.core.common.intecepter;

import cn.hutool.extra.servlet.ServletUtil;
import com.cwnu.sw.cys.core.common.domain.dto.ReqInfo;
import com.cwnu.sw.cys.core.common.utils.RequestHolder;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Optional;
/**
 * @author jisam
 * @version 1.0
 * @contact "jisamchan@outlook.com"
 * @date 13/02/2025
 * @description 该类是一个Spring拦截器，用于在请求处理前后执行特定操作。
 */
@Order(1)
@Slf4j
@Component
public class CollectionInterceptor implements HandlerInterceptor {

    /**
     * 在请求处理之前执行，用于初始化请求信息并将其存储在请求上下文中。
     *
     * @param request  HttpServletRequest对象，包含客户端请求的信息
     * @param response HttpServletResponse对象，用于向客户端发送响应
     * @param handler  处理请求的处理器对象
     * @return boolean 返回true表示继续处理请求，返回false表示中断请求处理
     */
    @Override
    public boolean preHandle(HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Object handler) {
        // 创建请求信息对象，并从请求中提取用户ID和客户端IP地址
        ReqInfo info = new ReqInfo();
        info.setUid(Optional.ofNullable(request.getAttribute(TokenInterceptor.ATTRIBUTE_UID))
                .map(Object::toString)
                .map(Long::parseLong)
                .orElse(null));
        info.setIp(ServletUtil.getClientIP(request));

        // 将请求信息存储在请求上下文中，以便后续处理使用
        RequestHolder.set(info);
        return true;
    }

    /**
     * 在请求处理完成后执行，用于清理请求上下文中的信息。
     *
     * @param request  HttpServletRequest对象，包含客户端请求的信息
     * @param response HttpServletResponse对象，用于向客户端发送响应
     * @param handler  处理请求的处理器对象
     * @param ex       请求处理过程中抛出的异常，如果没有异常则为null
     */
    @Override
    public void afterCompletion(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response,
                                @NotNull Object handler, Exception ex) {
        // 从请求上下文中移除请求信息，确保资源释放
        RequestHolder.remove();
    }
}

